package com.shoulder.core.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Copyright (c) 2024-2050 heguangchuan <596767880@qq.com>
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * <a href="http://www.apache.org/licenses/LICENSE-2.0">...</a>
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * <p>
 * 哎 太难了 没想到只是写着玩玩  却耐着性子一直写下来了
 *
 * @author 596767880@qq.com
 * @since 2024/5/11 上午11:52
 */
public class RecursionUtils {

    public static final String PARENT_ID = "parentId";
    public static final String ID = "id";
    public static final String CHILDREN = "children";

    public static <T> List<T> toList(List<Map<String, Object>> list, Class<T> elementType) {
        List<Map<String, Object>> recursive = recursive(list);
        return JsonUtils.json2List(JsonUtils.obj2Json(recursive), elementType);
    }


    public static List<Map<String, Object>> recursive(List<Map<String, Object>> list) {
        //查询最高的层级
        List<Map<String, Object>> parents = fetchParents(list);
        parents.forEach(parent -> buildTree(parent, list));
        return parents;
    }


    private static void buildTree(Map<String, Object> parentMap, List<Map<String, Object>> maps) {

        List<Map<String, Object>> children = maps.stream().filter(map -> map.get(PARENT_ID).equals(parentMap.get(ID)))
                .peek(map -> buildTree(map, maps))
                .toList();
        parentMap.put(CHILDREN, children);
    }

    private static List<Map<String, Object>> fetchParents(List<Map<String, Object>> list) {
        List<Map<String, Object>> dataList = new ArrayList<>();
        for (Map<String, Object> map : list) {
            Map<String, Object> objectMap = list.stream().filter(it -> it.get(ID).toString().equals(map.get(PARENT_ID))).findFirst().orElse(null);
            if (objectMap == null) {
                dataList.add(map);
            }
        }
        return dataList;
    }

    /**
     * 从集合中获取某个父对象的全部子集
     *
     * @param parentMap   父对象
     * @param maps        全体对象
     * @param children    返回的children列表
     * @param elementType 转化的bean类型
     * @param <T>         泛型对象
     * @return children
     */
    public static <T> List<T> getChildren(Map<String, Object> parentMap, List<Map<String, Object>> maps, List<T> children, Class<T> elementType) {

        List<Map<String, Object>> list = maps.stream().filter(map -> map.get(PARENT_ID).equals(parentMap.get(ID)))
                .peek(map -> getChildren(map, maps, children, elementType))
                .toList();
        children.addAll(toList(list, elementType));
        return children;
    }

}
